#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Last Update:

import sys
sys.path.append('.')
sys.path.append('..')
import wx
import wxHelper
import itertools
import config
from helper import main
from wx.lib.combotreebox import ComboTreeBox
import re

class MyDialog(wx.Dialog):
    def __init__(self, parent, log, name, **kwargs):
        wx.Dialog.__init__(self, parent, -1, name, **kwargs)
        self.log = log
        self.lblName = wx.StaticText(self, -1, u'建筑名称')
        self.cbName = ComboTreeBox(self, -1, u'请选择', style=wx.CB_READONLY)
        self.getBuildName()


        self.lblRank = wx.StaticText(self, -1, u'建筑级别')
        self.txtRank = wx.TextCtrl(self, -1, '')

        self.lblCity = wx.StaticText(self, -1, u'所属城区')
        cityList = [u'主城', u'第一分城', u'第二分城', u'第三分城', u'第四分城']
        self.cbCity = wx.ComboBox(self, -1, u'请选择', choices = cityList, style = wx.CB_DROPDOWN|wx.CB_READONLY)

        self.btnOk = wx.Button(self, wx.ID_OK, u'ok')
        self.btnCanel = wx.Button(self, wx.ID_CANCEL, u'canel')     
        self.layout()
        
    def layout(self):
        self.Center()
        titleSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
        titleSizer.AddGrowableCol(1)
        titleSizer.Add(self.lblName, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        titleSizer.Add(self.cbName, 0, wx.EXPAND)
        titleSizer.Add(self.lblRank, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        titleSizer.Add(self.txtRank, 0, wx.EXPAND)
        titleSizer.Add(self.lblCity, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        titleSizer.Add(self.cbCity, 0, wx.EXPAND)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.btnOk, 0, wx.ALL, 5)
        btnSizer.Add(self.btnCanel, 0, wx.ALL, 5)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(titleSizer, 0, wx.ALL, 5)
        mainSizer.Add(btnSizer, 0, wx.ALL, 5)
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    def getBuildName(self):
        child = self.cbName.Append(u'主城')
        for name in config.main_builds:
            self.cbName.Append(name, child)

        child = self.cbName.Append(u'封邑')
        for name in config.other_builds[0]:
            self.cbName.Append(name, child)

        child = self.cbName.Append(u'军镇')
        for name in config.other_builds[1]:
            self.cbName.Append(name, child)

class MainPanel(wx.Panel):
    def __init__(self, parent, log, dm, **kargs):
        wx.Panel.__init__(self, parent)
        self.log = log
        self.dm = dm
        self.main = main.Helper(log, dm, **kargs)

        self.btnGetBuilds = wx.Button(self, -1, u'获取可升级建筑物')
        self.Bind(wx.EVT_BUTTON, self.OnGetBuildsClick, self.btnGetBuilds)  

        self.treCanUpdate = wx.TreeCtrl(self, -1)

        self.lstUpdate = wxHelper.MyListCtrl(self, -1, style=wx.LC_REPORT)
        columns = [(u'名称', 60), (u'级别', 40), (u'城区', 80), (u'坐标', 80), (u'状态', 80)]
        columns.reverse()
        for name, width in columns:
            self.lstUpdate.InsertColumn(0, name)
            self.lstUpdate.SetColumnWidth(0, width)

        self.btnAdd = wx.Button(self, -1, u'添加->')
        self.btnDel = wx.Button(self, -1, u'<-删除')
        self.btnUp = wx.Button(self, -1, u'上升')
        self.btnDown = wx.Button(self, -1, u'下降')
        self.btnAppoint = wx.Button(self, -1, u'直接指定')
        
        self.Bind(wx.EVT_BUTTON, self.OnAddClick, self.btnAdd)  
        self.Bind(wx.EVT_BUTTON, self.lstUpdate.OnDelClick, self.btnDel)  
        self.Bind(wx.EVT_BUTTON, self.lstUpdate.OnUpClick, self.btnUp)  
        self.Bind(wx.EVT_BUTTON, self.lstUpdate.OnDownClick, self.btnDown)  
        self.Bind(wx.EVT_BUTTON, self.OnAppointClick, self.btnAppoint)  

        self.layout()
        self.init()

        self.hotKeyId_appoint = 101
        self.hotkey1_appoint, self.hotkey2_appoint = 'Alt', 'a'
        self.registerAppointHotkey()
        self.Bind(wx.EVT_HOTKEY, self.OnHotKeyAppoint, id=self.hotKeyId_appoint)

    def layout(self):
        self.Center()

        canUpdateBox = wx.StaticBox(self, -1, u'可升级建筑')
        canUpdateSizer = wx.StaticBoxSizer(canUpdateBox, wx.VERTICAL)
        canUpdateSizer.Add(self.btnGetBuilds, 0, wx.ALL, 5)
        canUpdateSizer.Add(self.treCanUpdate, 1, wx.ALL | wx.EXPAND, 5)

        btnSizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer.Add(self.btnAdd, 0, wx.ALL, 5)
        btnSizer.Add(self.btnDel, 0, wx.ALL, 5)
        btnSizer.Add(self.btnUp, 0, wx.ALL, 5)
        btnSizer.Add(self.btnDown, 0, wx.ALL, 5)
        btnSizer.Add((0, 0), 0, wx.ALL, 35)
        btnSizer.Add(self.btnAppoint, 0, wx.ALL, 5)

        updateBox = wx.StaticBox(self, -1, u'升级建筑列表')
        updateSizer = wx.StaticBoxSizer(updateBox, wx.VERTICAL)
        updateSizer.Add(self.lstUpdate, 1, wx.ALL | wx.EXPAND, 5)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(canUpdateSizer, 0, wx.EXPAND|wx.ALL, 5)
        mainSizer.Add(btnSizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        mainSizer.Add(updateSizer, 1, wx.EXPAND|wx.ALL, 5)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    def init(self):
        self.dialog = None
        import tools
        import pickle
        #data = tools.loadData('build.txt')
        #builds = pickle.loads(data)
        #self.main_builds= builds['main_builds']
        ##self.lstUpdate.appendItems(self.main_builds)

        #self.first_builds= builds['first_builds']
        #self.second_builds= builds['second_builds']

        #main_builds = [u'官府', u'城墙', u'民居', u'军营', u'书院', u'修炼馆', u'市场', u'酒馆', u'医馆', u'仓库', u'外使院', u'铁匠铺']
        #other_builds = [[u'司徒署', u'民居', u'工坊', u'地窖', u'角楼', u'祭坛'], [u'司马署',u'军营',u'操练场',u'炼丹炉',u'行营',u'哨塔']]

        #self.treCanUpdate.DeleteAllItems()
        #root = self.treCanUpdate.AddRoot(u'可升级建筑物')
        #item = self.treCanUpdate.AppendItem(root, u'主城(27)')
        #for build in main_builds:
            #self.treCanUpdate.AppendItem(item, build)
        #item = self.treCanUpdate.AppendItem(root, u'第一分城(27)')
        #for build in other_builds[1]:
            #self.treCanUpdate.AppendItem(item, build)
        #item = self.treCanUpdate.AppendItem(root, u'第二分城(13)')
        #for build in other_builds[0]:
            #self.treCanUpdate.AppendItem(item, build)

    def OnAddClick(self, event):
        def getTargetByName(name, builds):
            """得到范围内名称相同的最小级别的建筑, 取出后该建筑级别+1
            """
            item = None
            min_rank = 100
            for build in builds:
                if build[0] == name:
                    if build[1] < min_rank:
                        item = build
                        min_rank = build[1]
            if item:
                r = item[:]
                item[1] += 1 
            else:
                r = None
            return r

        def _getRealName(name):
            pos = name.find('(')
            if pos == -1:
                return name
            else:
                return name[:pos]

        def getSelect():
            item = self.treCanUpdate.GetSelection()
            item_name = self.treCanUpdate.GetItemText(item)
            item_name = _getRealName(item_name)
            try:
                parent_item = self.treCanUpdate.GetItemParent(item)
                parent_name = self.treCanUpdate.GetItemText(parent_item)
                parent_name = _getRealName(parent_name)
            except:
                parent_name = ''#对于根目录和一级目录
            return item_name,parent_name

        item_name, parent_name = getSelect()
        if parent_name:
            if parent_name == u'主城': 
                target = getTargetByName(item_name, self.main_builds)
            elif parent_name == u'第一分城': 
                target = getTargetByName(item_name, self.first_builds)
            elif parent_name == u'第二分城': 
                target = getTargetByName(item_name, self.second_builds)
            elif parent_name == u'第三分城': 
                target = getTargetByName(item_name, self.third_builds)
            elif parent_name == u'第四分城': 
                target = getTargetByName(item_name, self.fourth_builds)
            target.insert(2, parent_name)
            target.insert(4, config.updateStatus['wait'])
            self.lstUpdate.appendItem(target)
        else:
            wxHelper.msg(u'请选择需要升级的建筑')

        #import tools, pickle
        #data = {'main_builds':self.main_builds, 
                #'first_builds':self.first_builds, 
                #'second_builds':self.second_builds, 
                #'third_builds':self.third_builds, 
                #}
        #data = pickle.dumps(data)
        #tools.saveData('build.txt', data )
        #print 'ok'

    def OnAppointClick(self, event):
        #dialog = MyDialog(self, self.log, 'name', size = (200, 200))
        #dialog.cbName.SetValue(u'官府')
        #dialog.txtRank.SetValue('3')
        #dialog.cbCity.SetValue(u'主城')
        #result = dialog.ShowModal()
        #if result  ==  wx.ID_OK:
        print 'ok'
        #self.hotKeyId_appoint = 101
        #self.hotkey1, self.hotkey2 = 'Alt', 'a'
        #self.registerAppointHotkey(self.hotkey1, self.hotkey2)
        #self.Bind(wx.EVT_HOTKEY, self.OnHotKeyMin, id=self.hotKeyId_min)
        #self.Hide()

    def OnGetBuildsClick(self, evt):
        def _addTreeItems(root, self_builds, builds):
            if len(builds) == 2:
                bs = [b[0] for b in self_builds]
                if builds[0][0] in bs:
                    builds = builds[0]
                elif builds[1][0] in bs:
                    builds = builds[1]
                else:
                    return
            for build in builds:
                num = len(list(itertools.ifilter(lambda x:x[0] == build, self_builds)))
                item_value = u'%s(%s)' %(build, num)
                self.treCanUpdate.AppendItem(root, item_value)

        def addMainCity(root, builds):
            self.main.gotoMainCity()
            self.main_builds = self.main.findBuilds(builds)
            item_name = u'主城(%s)' %len(self.main_builds)
            item = self.treCanUpdate.AppendItem(root, item_name)
            _addTreeItems(item, self.main_builds, builds)

        def addFirstCity(root, builds):
            if self.main.gotoFirstCity():
                self.first_builds = self.main.findBuilds(builds)
                item_name = u'第一分城(%s)' %len(self.first_builds)
                item = self.treCanUpdate.AppendItem(root, item_name)
                _addTreeItems(item, self.first_builds, builds)

        def addSecondCity(root, builds):
            if self.main.gotoSecondCity():
                self.second_builds = self.main.findBuilds(builds)
                item_name = u'第二分城(%s)' %len(self.second_builds)
                item = self.treCanUpdate.AppendItem(root, item_name)
                _addTreeItems(item, self.second_builds, builds)

        def addThirdCity(root, builds):
            if self.main.gotoThirdCity():
                self.third_builds = self.main.findBuilds(builds)
                item_name = u'第三分城(%s)' %len(self.third_builds)
                item = self.treCanUpdate.AppendItem(root, item_name)
                _addTreeItems(item, self.third_builds, builds)

        def addFourthCity(root, builds):
            if self.main.gotoFourthCity():
                self.fourth_builds = self.main.findBuilds(builds)
                item_name = u'第四分城(%s)' %len(self.fourth_builds)
                item = self.treCanUpdate.AppendItem(root, item_name)
                _addTreeItems(item, self.fourth_builds, builds)


        self.treCanUpdate.DeleteAllItems()
        root = self.treCanUpdate.AddRoot(u'可升级建筑物')
        addMainCity(root, config.main_builds)
        addFirstCity(root, config.other_builds)
        addSecondCity(root, config.other_builds)
        addThirdCity(root, config.other_builds)
        addFourthCity(root, config.other_builds)

    def getData(self, data={}):
        data.update({'buildUpdates':self.lstUpdate.getItemsValues()})
        return data

    def setData(self, data):
        buildUpdates = data['buildUpdates']
        self.lstUpdate.appendItems(buildUpdates)

    def registerAppointHotkey(self):
        self.UnregisterHotKey(self.hotKeyId_appoint)
        choice1, choice2 = wxHelper.getHotkey(self.hotkey1_appoint, self.hotkey2_appoint)
        return self.RegisterHotKey(self.hotKeyId_appoint, choice1, choice2)

    def OnHotKeyAppoint(self, evt):
        if not self.dm.getWindowClass() == 'MacromediaFlashPlayerActiveX':
            self.log.info(u'进入游戏后才能执行此功能')
            return

        if self.dialog:
            self.dialog.Close()

        center_build, center_pos = self.main.getCenterBuildAndPos()
        self.log.debug('center_build:%s, pos:%s' %(center_build, center_pos))
        x, y = self.dm.getClientPos()
        strs = self.dm.ocr(x-53, y-37, x+69, y-8)
        self.log.debug(strs)

        name = self.getBuildName(strs)
        rank = self.getBuildRank(strs)
        pos = (x-center_pos[0], y-center_pos[1])

        self.dialog = MyDialog(self, self.log, u'建筑设置', size = (200, 200))
        if name: self.dialog.cbName.SetValue(name)
        if rank: self.dialog.txtRank.SetValue(rank)
        if center_build == u'官府': self.dialog.cbCity.SetValue(u'主城')
        result = self.dialog.ShowModal()
        if result  ==  wx.ID_OK:
            name = self.dialog.cbName.GetValue()
            rank = self.dialog.txtRank.GetValue()
            city = self.dialog.cbCity.GetValue()
            status = config.updateStatus['wait']
            item = [name, rank, city, pos, status]
            self.log.debug('select build %s' %str(item))
            self.lstUpdate.appendItem(item)

    ##########function##########
    def getBuildRank(self, str):
        """
        >>> getBuildRank(u'17d官府')
        17
        """
        p = re.compile(r'[^\d]*(?P<rank>\d{1,}).*')
        m = p.search(str)
        if m:
            return m.group('rank')
        else:
            return ''

    def getBuildName(self, str):
        builds = config.main_builds+config.other_builds[0]+config.other_builds[1]
        for build in builds:
            if str.find(build) != -1:
                return build
        return ''


